﻿/*======================================*\
* Author: Vincent
* LastModifyUser: Vincent
* Description:  
* CreateTime： 2012-05
* Remark:  
\*======================================*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Data;
using System.Linq;
using AppCode.Util;
using AppCode.DataHandler;
using AppCode.Contract;
using AppCode.Domain.Repositories;
using AppCode.DbDTO;
using System.ComponentModel;

namespace AppCode.Domain.Services
{
    /// <summary>
    /// 数据信息初始化
    /// </summary>
    public partial class DbInfoInit : ILoadDbInfoInit
    {
        #region 私有成员
        /// <summary>
        /// db操作，临时的
        /// </summary>
        private DataHanderExcute _db = null;

        /// <summary>
        /// 默认配置的路径信息
        /// </summary>
        private string _defaultConfigPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "ConfigXml\\DbConfig.xml";

        /// <summary>
        /// 得到数据库相关信息的sql(表字段相关)
        /// <remarks>
        /// 字符中占位{0}为表名
        /// </remarks>
        /// </summary>
        private static string _dbInfoSql = Vincent.AutoCode.Properties.Resources.DbInfoSql.ToString();

        /// <summary>
        /// 得到所有表信息
        /// </summary>
        private static string _dbUserTablesSql = Vincent.AutoCode.Properties.Resources.DbTablesSql.ToString();

        /// <summary>
        /// 得到所有视图信息
        /// </summary>
        private static string _dbAllView = Vincent.AutoCode.Properties.Resources.DbViewSql.ToString();

        /// <summary>
        /// 得到所有视图数
        /// </summary>
        private static string _dbAllViewCount = Vincent.AutoCode.Properties.Resources.DbViewCount.ToString();

        /// <summary>
        /// 所有用户表数
        /// </summary>
        private static string _dbUserTablesCount = Vincent.AutoCode.Properties.Resources.DbTablesCountsSql.ToString();

        /// <summary>
        /// 连接信息
        /// </summary>
        private static DbConnInfo _DbConnInfos = null;

        /// <summary>
        /// 异步DB操作的线程
        /// </summary>
        private BackgroundWorker _bgWorkReadDB = null;

        /// <summary>
        /// 读取表信息的后台线程
        /// </summary>
        private BackgroundWorker _bgWorkReadTbInfo = null;

         #endregion

        #region 私有方法
        /// <summary>
        /// 检查配置是否存在
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public bool CheckConfigIsHave(string path)
        {
            if (path == null)
                path = _defaultConfigPath;
            if (_DbConnInfos == null)
            {
                _DbConnInfos = SerializeHelper.SerializeXmlToObj<DbConnInfo>(path); //加载数据库连接信息(从配置)
                if (_DbConnInfos != null)
                    _db = new DataHanderExcute(_DbConnInfos.DbConnString);
                DbInfos = new DbInfo();
                DbInfos.DbConnStrInfo = _DbConnInfos;
                return true;
            }

            return false;
        }


        /// <summary>
        /// 加载表信息
        /// </summary>
        private void LoadDbTables()
        {
            if (DbInfos != null)
            {
                ReportStatusMsgEvent
                (
                    this,
                    new TaskInfoEventArgs() { msg = string.Format("开始读取数据库[{0}]所有用户表信息... ...", _DbConnInfos.DbName) }
                );

                #region 得到所有用户表数

                var tmpCountObj = _db.ExecuteScalar(_db.GetSqlStringCommond(_dbUserTablesCount));
                int userTablesCounts = tmpCountObj != null ? (int)tmpCountObj : 0;  //所有用户表数
                if (userTablesCounts < 1) throw new Exception("无法统计用户表数!");

                var tmpViewCount = _db.ExecuteScalar(_db.GetSqlStringCommond(_dbAllViewCount));
                int allViewCount = tmpViewCount != null ? (int)tmpViewCount : 0;
                

                #endregion

                IDataReader dr = _db.ExecuteReader(_db.GetSqlStringCommond(_dbUserTablesSql));
                if (dr != null)
                {
                    List<string> tmpTables = new List<string>();

                    decimal rd = 0m;  //进度条控制
                    int _rd = 1;

                    #region 读取用户表记录集
                    while (dr.Read())
                    {
                        string tbName = dr[0] != null ? dr[0].ToString() : "数据列异常";
                        rd++;
                        if (!tmpTables.Contains(tbName))
                        {
                            tmpTables.Add(tbName);
                            System.Threading.Thread.Sleep(2);
                            ReportStatusMsgEvent(this,new TaskInfoEventArgs() { msg = string.Format("加载表[{0}] ...", tbName) });

                            #region 通知进度条并创建树
                            var _m = Math.Round((rd / userTablesCounts)*100,2);  //转换%比
                            if (_m < 1)
                                _rd = 1;
                            else
                            {
                                _rd = (int)_m;
                                _bgWorkReadDB.ReportProgress(_rd);
                            }
                            LoadTreeInfoEvent(this, new TaskInfoEventArgs() { msg = tbName, value = "(表)" + tbName.ToUpper() }); //创建树
                            #endregion
                        }
                    }
                    dr.Close();
                    ReportStatusMsgEvent( this,new TaskInfoEventArgs() { msg = string.Format("[{0}]>所有用户表[{1}]个>读取完成,开始读取视图...", _DbConnInfos.DbName,
                                          userTablesCounts) });
                    System.Threading.Thread.Sleep(500);
                    #endregion
                    if (allViewCount > 0)
                    {
                        #region 读取视图记录集
                        using (var viewDr = _db.ExecuteReader(_db.GetSqlStringCommond(_dbAllView)))
                        {
                            rd = 0m;
                            _rd = 1;
                            
                            while (viewDr.Read())
                            {
                                string viewName = viewDr[0] != null ? viewDr[0].ToString() : "数据列异常";
                                rd++;
                                if (!tmpTables.Contains(viewName))
                                {
                                    tmpTables.Add(viewName);
                          
                                    System.Threading.Thread.Sleep(2);
                                    ReportStatusMsgEvent(this, new TaskInfoEventArgs() { msg = string.Format("加载表[{0}] ...", viewName) });

                                    #region 通知进度条并创建树
                                    var _m = Math.Round((rd / allViewCount) * 100, 2);  //转换%比
                                    if (_m < 1)
                                        _rd = 1;
                                    else
                                    {
                                        _rd = (int)_m;
                                        _bgWorkReadDB.ReportProgress(_rd);
                                    }
                                    LoadTreeInfoEvent(this, new TaskInfoEventArgs() { msg = viewName,value="(视图)"+viewName.ToUpper() }); //创建树
                                    #endregion
                                }
                            }
                            ReportStatusMsgEvent(this, new TaskInfoEventArgs()
                            {
                                msg = string.Format("[{0}]>所有视图[{1}]个>读取完成", _DbConnInfos.DbName,
                                    allViewCount)
                            });
                        }
                        #endregion
                    }
                    DbInfos.DbTables = tmpTables; //所有所有用户表和视图
                    DbInfos.DbTables.ToList().Sort();
                    DbInfos.DbConnStrInfo = _DbConnInfos;
                }
            }
        }
        #endregion


        #region 读DB线程事件
        /// <summary>
        /// 报告进度
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void bgWorkReadDB_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (ReportTaskProcessEvent != null)
                ReportTaskProcessEvent(this, new TaskInfoProcessEventArgs() { Process = e.ProgressPercentage });
        }

        /// <summary>
        /// 启动线程工作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void bgWork_DoWork(object sender, DoWorkEventArgs e)
        {
            LoadDbTables();
        }

        /// <summary>
        /// 执行完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void bgWorkReadDB_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
           
        }
        #endregion

        /// <summary>
        /// 数据库相关信息
        /// </summary>
        public static DbInfo DbInfos = null;

        #region IDbTreeCreate事件成员


        public event EventHandler<TaskInfoEventArgs> ReportStatusMsgEvent;

        public event EventHandler<TaskInfoProcessEventArgs> ReportTaskProcessEvent;

        public event EventHandler<TaskInfoEventArgs> LoadTreeInfoEvent;

        public event EventHandler<TaskInfoEventArgs> ReportTaskInfoToTextEvent;

        public event EventHandler BeginCreateCodeFile;
        #endregion


        /// <summary>
        /// 构造
        /// </summary>
        public DbInfoInit()
        {
            #region 异步读DB线程初始化

            _bgWorkReadDB = new BackgroundWorker() { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
            _bgWorkReadDB.DoWork += new DoWorkEventHandler(bgWork_DoWork);
            _bgWorkReadDB.ProgressChanged += new ProgressChangedEventHandler(bgWorkReadDB_ProgressChanged);
            _bgWorkReadDB.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorkReadDB_RunWorkerCompleted);
            #endregion

            #region 异步读取表字段信息线程初始化
            _bgWorkReadTbInfo = new BackgroundWorker() { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
            _bgWorkReadTbInfo.DoWork += new DoWorkEventHandler(bgWorkReadTbInfo_DoWork);
            _bgWorkReadTbInfo.ProgressChanged += new ProgressChangedEventHandler(bgWorkReadTbInfo_ProgressChanged);
            _bgWorkReadTbInfo.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorkReadTbInfo_RunWorkerCompleted);
            #endregion
        }



        /// <summary>
        /// 执行初始化
        /// </summary>
        public void DbOnInit()
        {
           var success =  CheckConfigIsHave(null);
           if (success)
               _bgWorkReadDB.RunWorkerAsync();
        }

    }
}
